package com.ruoyi.system.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.system.domain.EmailDetail;
import com.ruoyi.system.service.FileService;
import com.ruoyi.system.service.IAsyncDetailService;
import com.ruoyi.system.service.IEmailDetailService;
import com.ruoyi.system.service.IEmailService;
import lombok.extern.slf4j.Slf4j;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.Date;
import java.util.Set;

import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

@Service
@Slf4j
public class EmailServiceImpl implements IEmailService {
    @Value("${notification.mail.template.alarm:alarm}")
    private String alarmTemplate;

    @Value("${spring.mail.username}")
    private String from;

    @Autowired
    JavaMailSenderImpl mailSender;
    @Autowired
    private IEmailDetailService emailDetailService;
    @Autowired
    private IAsyncDetailService asyncDetailService;

    private String build(String template, JSONObject parameters) {
        String html = FileService.load(String.format("/notification/email/template/%s.htm", template), false);
        Document document = Jsoup.parse(html);
        Set<String> keys = parameters.keySet();
        for (String key : keys) {
            String value = parameters.getString(key);
            if (value == null) {
                continue;
            }
            Element field = document.getElementById(key);
            if (field == null) {
                continue;
            }
            field.html(value);
        }
        return document.toString();
    }

    @Async
    @Override
    public void send(String tid, JSONObject request) {
        Integer done = 0;
        EmailDetail emailDetail = new EmailDetail();
        JSONArray tos = null;
        String subject = null;
        Long companyId = null;
        String type = null;
        String template = null;
        JSONObject parameters = null;
        JSONArray attachments = null;
        boolean flag = false;
        try {
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
            InternetAddress from = new InternetAddress(this.from);
            mimeMessageHelper.setFrom(from);
            tos = request.getJSONArray("receivers");
            for (int i = 0; i < tos.size(); i++) {
                String item = tos.getString(i);
                InternetAddress to = new InternetAddress(item);
                mimeMessageHelper.setTo(to);
            }
            subject = request.getString("subject");
            companyId = request.getLong("companyId");
            type = request.getString("type");
            mimeMessageHelper.setSubject(subject);
            if ("alarm".equals(type)) {
                template = alarmTemplate;
            }
            parameters = request.getJSONObject("parameters");
            mimeMessageHelper.setText(build(template, parameters), true);
            attachments = request.getJSONArray("attachments");
            if (attachments != null) {
                for (int i = 0; i < attachments.size(); i++) {
                    JSONObject item = attachments.getJSONObject(i);
                    String name = item.getString("name");
                    String path = item.getString("path");
                    mimeMessageHelper.addAttachment(name, new File(String.format("files%s", path)));
                }
            }
            mailSender.send(mimeMessage);
            done = 1;
        } catch (Exception e) {
            log.info("",e);
            StackTraceElement[] traces = e.getStackTrace();
            for (StackTraceElement trace : traces) {
                log.debug(trace.toString());
            }
            flag = true;
            asyncDetailService.update(tid, 2, "邮件发送失败，失败原因：" + e.getMessage());
        }
        log.info("{} done:{}", tid, done);
        String html = FileService.load(String.format("/notification/email/template/%s.htm", template), false);
        emailDetail.setAttachments(JSONUtil.toJsonStr(attachments));
        emailDetail.setCompanyId(companyId);
        emailDetail.setParameters(JSONUtil.toJsonStr(parameters));
        emailDetail.setSubject(subject);
        emailDetail.setTemplate(template);
        emailDetail.setTid(tid);
        emailDetail.setFrom(from);
        emailDetail.setTo(JSONUtil.toJsonStr(tos));
        emailDetail.setType(type);
        emailDetail.setHtml(html);
        emailDetail.setFlag(done);
        emailDetail.setCreateTime(new Date());
        emailDetailService.add(emailDetail);
        if (!flag){
            asyncDetailService.update(tid,1,null);
        }
    }
}
